﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Slick.MapEditor;
using Clandestine;

namespace Slick
{
    public partial class LayerControl : UserControl
    {
        public Map Map;

        private class NoSelectedLayerException : Exception { }

        public LayerControl()
        {
            InitializeComponent();
        }

        public void Initialise(Map map)
        {
            this.Map = map;

            // Setup event handlers
            Map.Layers.OnLayerAdd += new LayerAddDelegate(AddComplete);
            Map.Layers.OnLayerDelete += new LayerDeleteDelegate(DeleteComplete);
            Map.Layers.OnLayersCleared += new LayersClearedDelegate(Layers_OnLayersCleared);

            // Add initial layer
            Map.Layers.Add(0);
        }

        void Layers_OnLayersCleared()
        {
            listLayers.Items.Clear();
        }

        public void Add()
        {
            // Get depth
            decimal depth = 0;
            frmLayerDepth dialog = new frmLayerDepth();
            if (dialog.ShowAddDialog() == DialogResult.OK)
            {
                depth = dialog.updDepth.Value;

                // Start add!
                Map.Layers.Add(depth);
            }
        }

        public void AddComplete(Layer l)
        {
            listLayers.Items.Add(l); // add the actual layer so ID is preserved; Layer.ToString()
                                     // takes care of showing the depth in the list.
            listLayers.SelectedItem = l; // select it
        }

        public void DeleteSelected()
        {
            // Check we aren't deleting the last one
            if (listLayers.Items.Count == 1)
            {
                // Yell at them.
                MessageBox.Show("That's the last layer!\n\nTo remove all layers either click Level > New,"
                         + " or create a new layer and *then* delete this one.", "Cannot delete last layer",
                         MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Get selected
            Layer l = null;
            try
            {
                l = getSelectedItem();
            }
            catch (NoSelectedLayerException e)
            {
                MessageBox.Show("Could not delete the selected layer because no layer is currently selected.",
                        "Could not delete layer", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            // Are you sure
            DialogResult result = MessageBox.Show("Are you sure you want to delete the selected layer?", "Delete selected layer?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.No)
                return;

            // Delete the selected
            Delete(l.ID);
            listLayers.SelectedIndex = 0; // select SOMETHING
        }

        public void Delete(int id)
        {
            // Start deletion
            Map.Layers.Delete(id);
        }

        public void DeleteComplete(int id)
        {
            // Delete from list
            for (int i = 0; i < listLayers.Items.Count; i++)
                if (((Layer)listLayers.Items[i]).ID == id)
                    listLayers.Items.RemoveAt(i);
        }

        private Layer getSelectedItem()
        {
            Layer l = ((Layer)listLayers.SelectedItem);
            if (l == null)
                throw new NoSelectedLayerException();
            return l;
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            Add();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            DeleteSelected();
        }

        private void changeDepthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Get selected
            Layer l;
            try
            {
                l = getSelectedItem();
            }
            catch (NoSelectedLayerException ex)
            {
                MessageBox.Show("Could not change the depth of the selected layer because no layer is currently selected.",
                        "Could not change layer depth", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Find out the new depth we want.
            frmLayerDepth dialog = new frmLayerDepth();
            decimal depth = l.Depth;
            if (dialog.ShowModifyDialog(depth) == DialogResult.OK)
            {
                depth = dialog.updDepth.Value;
                l.Depth = depth;
                listLayers.Items.Remove(l);
                listLayers.Items.Add(l); // RLY? Think we need this to make the label change.
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Get selected
            Layer l = null;
            try
            {
                l = getSelectedItem();
            }
            catch (NoSelectedLayerException ex)
            {
                MessageBox.Show("Could not clone the selected layer because no layer is currently selected.",
                        "Could not clone layer", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            // Get depth
            frmLayerDepth dialog = new frmLayerDepth();
            if (dialog.ShowAddDialog() == DialogResult.OK)
            {
                decimal depth = dialog.updDepth.Value;

                // Clone!
                Map.Layers.CloneLayer(l, depth);
            }
        }

        private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            DeleteSelected();
        }

        private void listLayers_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Find ID of selected layer!
            Layer l = getSelectedItem();
            for (int i = 0; i < Map.Layers.Layers.Count; i++)
                if (Map.Layers[i] == l)
                {
                    Map.Layers.SelectedLayerID = i;
                    return;
                }
           
            // If we get this far, something has gone wrong!
            Log.e("Failed to change layer!");
        }
    }
}
